// Vue.js 专项自动评分系统
import type { GradingResult } from '@/types'

/**
 * Vue.js 作业评分配置
 */
export interface VueAssignmentConfig {
  id: number
  title: string
  type: 'vue-basic' | 'vue-component' | 'vue-advanced'
  criteria: {
    vueBasics: { weight: number; requirements: string[] }
    dataBinding: { weight: number; requirements: string[] }
    directives: { weight: number; requirements: string[] }
    styling: { weight: number; requirements: string[] }
    structure: { weight: number; requirements: string[] }
  }
}

/**
 * Vue.js 课程作业配置
 */
export const VUE_ASSIGNMENTS_CONFIG: Record<string, VueAssignmentConfig> = {
  'personal-info-card': {
    id: 1,
    title: '个人信息卡制作',
    type: 'vue-basic',
    criteria: {
      vueBasics: {
        weight: 30,
        requirements: [
          'Vue实例创建和挂载',
          'data属性定义',
          '插值语法{{}}使用'
        ]
      },
      dataBinding: {
        weight: 25,
        requirements: [
          '个人信息数据绑定',
          '姓名、年龄、专业、爱好显示',
          '数据响应式更新'
        ]
      },
      directives: {
        weight: 20,
        requirements: [
          'v-if/v-show条件渲染',
          'v-for列表渲染（如爱好列表）',
          'v-bind属性绑定'
        ]
      },
      styling: {
        weight: 15,
        requirements: [
          'CSS样式美化',
          '布局合理性',
          '视觉效果'
        ]
      },
      structure: {
        weight: 10,
        requirements: [
          'HTML结构清晰',
          '代码组织良好',
          '注释完整'
        ]
      }
    }
  }
}

/**
 * Vue.js 专项评分引擎
 */
export class VueGradingEngine {
  /**
   * 评分Vue.js作业
   * @param code 学生代码
   * @param assignmentKey 作业配置键
   * @returns 评分结果
   */
  static async gradeVueAssignment(
    code: string,
    assignmentKey: string
  ): Promise<GradingResult> {
    const config = VUE_ASSIGNMENTS_CONFIG[assignmentKey]
    if (!config) {
      throw new Error(`未找到作业配置: ${assignmentKey}`)
    }

    const result: GradingResult = {
      score: 0,
      maxScore: 100,
      details: {
        vueBasics: { score: 0, maxScore: config.criteria.vueBasics.weight, feedback: '' },
        dataBinding: { score: 0, maxScore: config.criteria.dataBinding.weight, feedback: '' },
        directives: { score: 0, maxScore: config.criteria.directives.weight, feedback: '' },
        styling: { score: 0, maxScore: config.criteria.styling.weight, feedback: '' },
        structure: { score: 0, maxScore: config.criteria.structure.weight, feedback: '' }
      },
      feedback: '',
      grade: 'F'
    }

    // 1. Vue基础语法检查
    const vueBasicsResult = this.checkVueBasics(code, config.criteria.vueBasics)
    result.details.vueBasics = vueBasicsResult
    result.score += vueBasicsResult.score

    // 2. 数据绑定检查
    const dataBindingResult = this.checkDataBinding(code, config.criteria.dataBinding)
    result.details.dataBinding = dataBindingResult
    result.score += dataBindingResult.score

    // 3. 指令使用检查
    const directivesResult = this.checkDirectives(code, config.criteria.directives, assignmentKey)
    result.details.directives = directivesResult
    result.score += directivesResult.score

    // 4. 样式检查
    const stylingResult = this.checkStyling(code, config.criteria.styling)
    result.details.styling = stylingResult
    result.score += stylingResult.score

    // 5. 结构检查
    const structureResult = this.checkStructure(code, config.criteria.structure)
    result.details.structure = structureResult
    result.score += structureResult.score

    // 生成等级
    result.grade = this.calculateGrade(result.score)

    // 生成综合反馈
    result.feedback = this.generateFeedback(result)

    return result
  }

  /**
   * 检查Vue基础语法
   */
  private static checkVueBasics(
    code: string,
    criteria: { weight: number; requirements: string[] }
  ): { score: number; maxScore: number; feedback: string } {
    let score = 0
    const maxScore = criteria.weight
    const feedback: string[] = []

    // 检查Vue 3 CDN引入
    if (code.includes('https://unpkg.com/vue@3') || code.includes('vue@3')) {
      score += maxScore * 0.15
      feedback.push('✅ 正确引入Vue 3 CDN')
    } else {
      feedback.push('💡 建议使用Vue 3 CDN')
    }

    // 检查Vue实例创建（优先Vue 3语法）
    if (code.includes('createApp(') && code.includes('.mount(')) {
      score += maxScore * 0.4
      feedback.push('✅ 使用Vue 3 createApp语法')
    } else if (code.includes('new Vue(') || code.includes('Vue.createApp(')) {
      score += maxScore * 0.3
      feedback.push('✅ Vue实例创建正确，建议使用Vue 3语法')
    } else {
      feedback.push('❌ 缺少Vue实例创建')
    }

    // 检查Composition API setup函数
    if (code.includes('setup()')) {
      score += maxScore * 0.25
      feedback.push('✅ 使用了Composition API setup函数')
    } else if (code.includes('data:') || code.includes('data()')) {
      score += maxScore * 0.15
      feedback.push('✅ 使用了data属性，建议尝试setup函数')
    } else {
      feedback.push('❌ 缺少数据定义（setup或data）')
    }

    // 检查插值语法
    if (code.includes('{{') && code.includes('}}')) {
      score += maxScore * 0.2
      feedback.push('✅ 使用了插值语法')
    } else {
      feedback.push('❌ 未使用插值语法显示数据')
    }

    return {
      score: Math.round(score),
      maxScore,
      feedback: feedback.join('\n')
    }
  }

  /**
   * 检查数据绑定
   */
  private static checkDataBinding(
    code: string,
    criteria: { weight: number; requirements: string[] }
  ): { score: number; maxScore: number; feedback: string } {
    let score = 0
    const maxScore = criteria.weight
    const feedback: string[] = []

    // 检查标准答案中的必需字段（支持ES6简写语法和完整语法）
    const requiredFields = {
      title: /title["']?\s*:\s*["']个人信息展示["']/,
      // 支持 name: "value" 和 name, 两种写法
      name: /(?:name["']?\s*:\s*["'][^"']*["']|\bname\s*[,}])/,
      // 支持 age: 25 和 age, 两种写法
      age: /(?:age["']?\s*:\s*\d+|\bage\s*[,}])/,
      major: /major["']?\s*:\s*["'][^"']*["']/,
      hobby: /hobby["']?\s*:\s*["'][^"']*["']/
    }

    let foundFieldsCount = 0
    const foundFieldNames: string[] = []

    Object.entries(requiredFields).forEach(([fieldName, pattern]) => {
      if (pattern.test(code)) {
        foundFieldsCount++
        foundFieldNames.push(fieldName)
      }
    })

    if (foundFieldsCount >= 4) {
      score += maxScore * 0.5
      feedback.push(`✅ 包含必需字段: ${foundFieldNames.join(', ')}`)
    } else {
      feedback.push(`❌ 缺少必需字段，当前只有: ${foundFieldNames.join(', ')}`)
    }

    // 检查数据绑定语法（插值表达式）
    const bindingPatterns = /{{\s*(title|name|age|major|hobby)\s*}}/g
    const bindings = code.match(bindingPatterns)
    if (bindings && bindings.length >= 4) {
      score += maxScore * 0.4
      feedback.push(`✅ 正确使用了${bindings.length}个数据绑定`)
    } else if (bindings && bindings.length >= 2) {
      score += maxScore * 0.2
      feedback.push(`✅ 使用了${bindings.length}个数据绑定，建议绑定更多字段`)
    } else {
      feedback.push('❌ 数据绑定使用不足或字段名不匹配')
    }

    // 检查return语句（Composition API）
    if (code.includes('return {') && foundFieldsCount >= 3) {
      score += maxScore * 0.1
      feedback.push('✅ 正确使用return返回数据')
    }

    return {
      score: Math.round(score),
      maxScore,
      feedback: feedback.join('\n')
    }
  }

  /**
   * 检查Vue指令使用
   */
  private static checkDirectives(
    code: string,
    criteria: { weight: number; requirements: string[] },
    assignmentType: string = 'personal-info-card'
  ): { score: number; maxScore: number; feedback: string } {
    let score = 0
    const maxScore = criteria.weight
    const feedback: string[] = []

    // 根据作业类型调整评分策略
    if (assignmentType === 'personal-info-card') {
      // 个人信息卡：主要考查插值表达式和基础数据绑定
      
      // 检查插值表达式 {{ }} - 这是核心要求
      const interpolationMatches = code.match(/{{\s*\w+\s*}}/g)
      if (interpolationMatches && interpolationMatches.length >= 3) {
        score += maxScore * 0.8
        feedback.push(`✅ 正确使用插值表达式显示数据 (发现${interpolationMatches.length}处)`)
      } else if (interpolationMatches && interpolationMatches.length > 0) {
        score += maxScore * 0.6
        feedback.push(`✅ 使用了插值表达式，但数量较少 (发现${interpolationMatches.length}处)`)
      } else {
        feedback.push('❌ 未发现插值表达式 {{ }}，这是Vue数据绑定的基础语法')
      }

      // 检查v-text或v-html（替代方案）
      if (code.includes('v-text') || code.includes('v-html')) {
        score += maxScore * 0.1
        feedback.push('✅ 使用了v-text或v-html指令作为数据绑定的替代方案')
      }

      // 对于个人信息卡，其他指令是可选的加分项
      if (code.includes('v-if') || code.includes('v-show')) {
        score += maxScore * 0.05
        feedback.push('✅ 额外加分：使用了条件渲染指令')
      }

      if (code.includes('v-for')) {
        score += maxScore * 0.05
        feedback.push('✅ 额外加分：使用了列表渲染指令')
      }

      // 如果没有使用插值表达式但使用了其他Vue特性，给予部分分数
      if (score === 0 && (code.includes('v-') || code.includes('Vue') || code.includes('createApp'))) {
        score += maxScore * 0.3
        feedback.push('⚠️ 检测到Vue相关代码，但建议使用插值表达式 {{ }} 来显示数据')
      }

    } else {
      // 其他类型作业的评分逻辑（保持原有逻辑）
      if (code.includes('v-if') || code.includes('v-show')) {
        score += maxScore * 0.3
        feedback.push('✅ 使用了条件渲染指令')
      }

      if (code.includes('v-for')) {
        score += maxScore * 0.3
        feedback.push('✅ 使用了列表渲染指令')
      }

      if (code.includes('v-bind') || code.includes(':class') || code.includes(':style')) {
        score += maxScore * 0.2
        feedback.push('✅ 使用了属性绑定')
      }

      if (code.includes('v-model')) {
        score += maxScore * 0.2
        feedback.push('✅ 使用了双向数据绑定')
      }
    }

    // 确保分数不超过最大值
    score = Math.min(score, maxScore)

    return {
      score: Math.round(score),
      maxScore,
      feedback: feedback.join('\n')
    }
  }

  /**
   * 检查样式和布局
   */
  private static checkStyling(
    code: string,
    criteria: { weight: number; requirements: string[] }
  ): { score: number; maxScore: number; feedback: string } {
    let score = 0
    const maxScore = criteria.weight
    const feedback: string[] = []

    // 检查CSS样式块
    if (code.includes('<style>') && code.includes('</style>')) {
      score += maxScore * 0.3
      feedback.push('✅ 包含CSS样式块')
    } else {
      feedback.push('❌ 缺少CSS样式块')
    }

    // 检查标准答案中的关键CSS类
    const cssClasses = {
      'info-card': /\.info-card\s*{[^}]*}/,
      'info-item': /\.info-item\s*{[^}]*}/
    }

    let foundClasses = 0
    Object.entries(cssClasses).forEach(([className, pattern]) => {
      if (pattern.test(code)) {
        foundClasses++
        feedback.push(`✅ 定义了${className}类样式`)
      }
    })

    if (foundClasses >= 2) {
      score += maxScore * 0.4
    } else if (foundClasses >= 1) {
      score += maxScore * 0.2
      feedback.push('💡 建议添加更多样式类')
    }

    // 检查关键样式属性
    const styleProperties = [
      'background-color',
      'padding',
      'border-radius',
      'box-shadow',
      'border-left'
    ]

    const foundProperties = styleProperties.filter(prop => 
      code.includes(prop)
    )

    if (foundProperties.length >= 3) {
      score += maxScore * 0.2
      feedback.push(`✅ 使用了丰富的样式属性: ${foundProperties.slice(0, 3).join(', ')}`)
    } else if (foundProperties.length >= 1) {
      score += maxScore * 0.1
      feedback.push('💡 建议使用更多样式属性美化界面')
    }

    // 检查布局结构
    if (code.includes('class="info-card"') && code.includes('class="info-item"')) {
      score += maxScore * 0.1
      feedback.push('✅ 正确使用了样式类')
    }

    return {
      score: Math.round(score),
      maxScore,
      feedback: feedback.join('\n')
    }
  }

  /**
   * 检查代码结构
   */
  private static checkStructure(
    code: string,
    criteria: { weight: number; requirements: string[] }
  ): { score: number; maxScore: number; feedback: string } {
    let score = 0
    const maxScore = criteria.weight
    const feedback: string[] = []

    // 检查HTML5文档结构
    const htmlStructure = {
      doctype: /<!DOCTYPE html>/i,
      html: /<html[^>]*>/i,
      head: /<head>/i,
      body: /<body>/i,
      title: /<title>[^<]*个人信息[^<]*<\/title>/i
    }

    let structureScore = 0
    Object.entries(htmlStructure).forEach(([element, pattern]) => {
      if (pattern.test(code)) {
        structureScore++
        if (element === 'title') {
          feedback.push('✅ 页面标题设置正确')
        }
      }
    })

    if (structureScore >= 4) {
      score += maxScore * 0.4
      feedback.push('✅ HTML5文档结构完整')
    } else {
      feedback.push('❌ HTML文档结构不完整')
    }

    // 检查Vue应用挂载点
    if (code.includes('id="app"') && code.includes('.mount("#app")')) {
      score += maxScore * 0.3
      feedback.push('✅ Vue应用挂载点配置正确')
    } else if (code.includes('id="app"') || code.includes('.mount(')) {
      score += maxScore * 0.15
      feedback.push('💡 Vue挂载配置需要完善')
    } else {
      feedback.push('❌ 缺少Vue应用挂载配置')
    }

    // 检查meta标签
    if (code.includes('charset="UTF-8"') && code.includes('viewport')) {
      score += maxScore * 0.2
      feedback.push('✅ 包含必要的meta标签')
    } else {
      feedback.push('💡 建议添加charset和viewport meta标签')
    }

    // 检查代码组织
    const hasStyleSection = code.includes('<style>') && code.includes('</style>')
    const hasScriptSection = code.includes('<script>') && code.includes('</script>')
    
    if (hasStyleSection && hasScriptSection) {
      score += maxScore * 0.1
      feedback.push('✅ 代码结构组织良好（样式和脚本分离）')
    }

    return {
      score: Math.round(score),
      maxScore,
      feedback: feedback.join('\n')
    }
  }

  /**
   * 计算等级
   */
  private static calculateGrade(score: number): string {
    if (score >= 90) return 'A'
    if (score >= 80) return 'B'
    if (score >= 70) return 'C'
    if (score >= 60) return 'D'
    return 'F'
  }

  /**
   * 生成综合反馈
   */
  private static generateFeedback(result: GradingResult): string {
    const feedback: string[] = []
    
    feedback.push(`📊 总分: ${result.score}/100 (${result.grade}级)`)
    feedback.push('')
    
    // 各项详细反馈
    Object.entries(result.details).forEach(([key, detail]) => {
      // 类型安全检查：确保detail存在且不为undefined
      if (!detail || typeof detail !== 'object') {
        return
      }
      
      const sectionName = {
        vueBasics: 'Vue基础语法',
        dataBinding: '数据绑定',
        directives: 'Vue指令',
        styling: '样式布局',
        structure: '代码结构'
      }[key] || key
      
      feedback.push(`🔍 ${sectionName}: ${detail.score}/${detail.maxScore}分`)
      if (detail.feedback) {
        feedback.push(detail.feedback)
      }
      feedback.push('')
    })
    
    // 总体建议
    if (result.score >= 90) {
      feedback.push('🎉 优秀！你的Vue.js代码质量很高，继续保持！')
    } else if (result.score >= 80) {
      feedback.push('👍 良好！代码基本符合要求，可以进一步优化细节。')
    } else if (result.score >= 70) {
      feedback.push('✅ 及格！基础功能实现了，建议加强Vue语法的使用。')
    } else {
      feedback.push('📚 需要改进！建议复习Vue.js基础语法和数据绑定概念。')
    }
    
    return feedback.join('\n')
  }
}

/**
 * 便捷的Vue作业评分函数
 */
export async function gradeVueAssignment(
  code: string,
  assignmentKey: string = 'personal-info-card'
): Promise<GradingResult> {
  return VueGradingEngine.gradeVueAssignment(code, assignmentKey)
}